﻿#include "parametertablemodel.h"

/**
 * @brief ParameterTableModel::ParameterTableModel
 * @details 构造参数表模型并绑定父对象。
 * @param p Qt 父对象。
 */
ParameterTableModel::ParameterTableModel(QObject *p)
    : QAbstractTableModel(p)
{
}

/**
 * @brief ParameterTableModel::setTransducerSourceUnit
 * @details 更新换能器源单位并刷新表头。
 * @param unit 源单位字符串。
 */
void ParameterTableModel::setTransducerSourceUnit(const QString &unit)
{
    if (m_kind != ParamTableKind::Transducer) {
        return; // 只对 Transducer 类型有效
    }
    if (m_trans.sourceUnit != unit) {
        m_trans.sourceUnit = unit;
        emit headerDataChanged(Qt::Horizontal, 0, 0);
    }
}

/**
 * @brief ParameterTableModel::setTransducerTargetUnit
 * @details 更新换能器目标单位并刷新表头。
 * @param unit 目标单位字符串。
 */
void ParameterTableModel::setTransducerTargetUnit(const QString &unit)
{
    if (m_kind != ParamTableKind::Transducer) {
        return;
    }
    int targetColumnIndex = this->columnCount() - 1; // 最后一列
    if (m_trans.targetUnit != unit) {
        m_trans.targetUnit = unit;
        emit headerDataChanged(Qt::Horizontal, targetColumnIndex, targetColumnIndex);
    }
}
/**
 * @brief ParameterTableModel::setKind
 * @details 设置模型类型并重置数据。
 * @param k 参数表类型。
 */
void ParameterTableModel::setKind(ParamTableKind k)
{
    if (m_kind == k)
        return;
    beginResetModel();
    m_kind = k;
    m_customHeader.clear(); // 切换类型时清空自定义表头
    endResetModel();
}
/**
 * @brief ParameterTableModel::setHeaderText
 * @details 设置指定列的自定义表头文本。
 * @param column 列索引。
 * @param text 表头文本。
 */
void ParameterTableModel::setHeaderText(int column, const QString &text)
{
    if (column < 0 || column >= columnCount())
        return;
    if (m_customHeader.value(column) == text)
        return;
    m_customHeader[column] = text;
    emit headerDataChanged(Qt::Horizontal, column, column); // 只刷新这一列的表头
}

/**
 * @brief ParameterTableModel::applyNonCalHeaders
 * @details 根据单位更新非校准表的表头。
 * @param freqUnit 频率单位。
 * @param valUnit 数值单位。
 */
void ParameterTableModel::applyNonCalHeaders(const QString &freqUnit, const QString &valUnit)
{
    auto mk = [&](const QString &name, const QString &unit) {
        return unit.isEmpty() ? name : QString("%1(%2)").arg(name, unit);
    };

    switch (m_kind) {
    case ParamTableKind::Attenuation:
        setHeaderText(0, mk(tr("Frequency"), freqUnit));
        setHeaderText(1, mk(tr("Attenuation"), valUnit));
        break;
    case ParamTableKind::Transducer:
        setHeaderText(1, mk(tr("Frequency"), freqUnit));
        break;
    case ParamTableKind::LimitLine:
        setHeaderText(0, mk(tr("Frequency"), freqUnit));
        setHeaderText(1, mk(tr("Limit"), valUnit));
        break;
    case ParamTableKind::Frequency:
        setHeaderText(0, mk(tr("Frequency"), freqUnit));
        break;
    case ParamTableKind::Cal:
        setHeaderText(1, mk(tr("Frequency"), freqUnit));
        setHeaderText(5, mk(tr("ImmunityLevel"), valUnit));
        setHeaderText(6, mk(tr("LimitImmunityLevel"), valUnit));
        break;
    }
}

/**
 * @brief ParameterTableModel::setDataAtt
 * @details 设置衰减表数据并刷新模型。
 * @param list 衰减表列表。
 */
void ParameterTableModel::setDataAtt(const AttTableList &list)
{
    beginResetModel();
    m_att = list;
    endResetModel();
}
/**
 * @brief ParameterTableModel::setDataTransducer
 * @details 设置换能器表数据并刷新模型。
 * @param list 换能器表列表。
 */
void ParameterTableModel::setDataTransducer(const TransducerTableList &list)
{
    beginResetModel();
    m_trans = list;
    endResetModel();
}
/**
 * @brief ParameterTableModel::setDataLimitLine
 * @details 设置极限线表数据并刷新模型。
 * @param list 极限线列表。
 */
void ParameterTableModel::setDataLimitLine(const LimitLineList &list)
{
    beginResetModel();
    m_limit = list;
    endResetModel();
}
/**
 * @brief ParameterTableModel::setDataFreq
 * @details 设置频率表数据并刷新模型。
 * @param rows 频率配置列表。
 */
void ParameterTableModel::setDataFreq(const QList<FreqTableConfig> &rows)
{
    beginResetModel();
    m_freq = rows;
    endResetModel();
}
/**
 * @brief ParameterTableModel::setDataCal
 * @details 设置校准表数据并刷新模型。
 * @param rows 校准配置列表。
 */
void ParameterTableModel::setDataCal(const QList<CalTableConfig> &rows)
{
    beginResetModel();
    m_cal = rows;
    endResetModel();
}

/**
 * @brief ParameterTableModel::rowCount
 * @details 返回当前数据集中行数。
 * @param parent 父索引。
 * @return 行数。
 */
int ParameterTableModel::rowCount(const QModelIndex &) const
{
    switch (m_kind) {
    case ParamTableKind::Attenuation:
        return m_att.attList.size();
    case ParamTableKind::Transducer:
        return m_trans.factorsList.size();
    case ParamTableKind::LimitLine:
        return m_limit.limitList.size();
    case ParamTableKind::Frequency:
        return m_freq.size();
    case ParamTableKind::Cal:
        return m_cal.size();
    }
    return 0;
}
/**
 * @brief ParameterTableModel::cols
 * @details 根据模型类型返回列数。
 * @return 列数。
 */
int ParameterTableModel::cols() const
{
    switch (m_kind) {
    case ParamTableKind::Attenuation:
        return 2; // Freq, Att
    case ParamTableKind::Transducer:
        return 4; // Freq, Factors
    case ParamTableKind::LimitLine:
        return 2; // Freq, Limit
    case ParamTableKind::Frequency:
        return 1; // Freq
    case ParamTableKind::Cal:
        return 12; // 见结构
    }
    return 0;
}
/**
 * @brief ParameterTableModel::columnCount
 * @details 返回当前模型的列数。
 * @param parent 父索引。
 * @return 列数。
 */
int ParameterTableModel::columnCount(const QModelIndex &) const
{
    return cols();
}

/**
 * @brief ParameterTableModel::headerData
 * @details 返回表头显示数据。
 * @param section 列索引。
 * @param o 方向。
 * @param role 数据角色。
 * @return 表头文本。
 */
QVariant ParameterTableModel::headerData(int section, Qt::Orientation o, int role) const
{
    if (o != Qt::Horizontal || role != Qt::DisplayRole)
        return {};
    // 优先返回自定义标题
    if (m_customHeader.contains(section))
        return m_customHeader.value(section);
    switch (m_kind) {
    case ParamTableKind::Attenuation:
        return (QStringList {tr("Frequency"), tr("Attenuation")}).value(section);
    case ParamTableKind::Transducer:
        return (QStringList {tr("SourceUnit"), tr("Frequency"), tr("Factors"), tr("TargetUnit")}).value(section);
    case ParamTableKind::LimitLine:
        return (QStringList {tr("Frequency"), tr("Limit")}).value(section);
    case ParamTableKind::Frequency:
        return (QStringList {tr("Frequency")}).value(section);
    case ParamTableKind::Cal: {
        static QStringList hh = {"ID", tr("Frequency"), tr("Amplitude"), tr("FwdPower"), tr("RevPower"), tr("ImmunityLevel"), tr("LimitImmunityLevel"), tr("SWR"), tr("Loss"), tr("CloseLoop"), tr("Info")};
        return hh.value(section);
    }
    default:
        break;
    }

    return {};
}

/**
 * @brief ParameterTableModel::data
 * @details 返回单元格数据或勾选状态。
 * @param idx 模型索引。
 * @param role 数据角色。
 * @return 单元格内容。
 */
QVariant ParameterTableModel::data(const QModelIndex &idx, int role) const
{
    if (!idx.isValid())
        return {};
    const int r = idx.row(), c = idx.column();

    auto dispNum = [&](double v) { return role == Qt::DisplayRole || role == Qt::EditRole ? QVariant(v) : QVariant(); };
    auto dispStr = [&](const QString &s) { return role == Qt::DisplayRole || role == Qt::EditRole ? QVariant(s) : QVariant(); };

    switch (m_kind) {
    case ParamTableKind::Attenuation:
        if (r < m_att.attList.size())
            return c == 0 ? dispNum(m_att.attList[r].Freq / 1e6) : dispNum(m_att.attList[r].Att);
        break;
    case ParamTableKind::Transducer:
        if (r < m_trans.factorsList.size()) {
            switch (c) {
            case 0:                                                // Source Unit (第一列)
                return dispStr(m_trans.sourceUnit);                // 返回 QString
            case 1:                                                // Frequency (第二列)
                return dispNum(m_trans.factorsList[r].Freq / 1e6); // MHz
            case 2:                                                // Factors (第三列)
                return dispNum(m_trans.factorsList[r].Factors);
            case 3:                                 // Target Unit (第四列)
                return dispStr(m_trans.targetUnit); // 返回 QString
            }
        }
        break;
    case ParamTableKind::LimitLine:
        if (r < m_limit.limitList.size())
            return c == 0 ? dispNum(m_limit.limitList[r].Freq / 1e6) : dispNum(m_limit.limitList[r].Limit);
        break;
    case ParamTableKind::Frequency:
        if (r < m_freq.size())
            return c == 0 ? dispNum(m_freq[r].Freq / 1e6) : QVariant();
        break;
    case ParamTableKind::Cal:
        if (r < m_cal.size()) {
            const auto &x = m_cal[r];
            if (role == Qt::CheckStateRole && c == 9) // CloseLoop 复选
                return x.CloseLoop ? Qt::Checked : Qt::Unchecked;

            if (role == Qt::DisplayRole || role == Qt::EditRole) {
                switch (c) {
                case 0:
                    break;
                case 1:
                    return x.Freq / 1e6;
                case 2:
                    return x.Amplitude;
                case 3:
                    return x.FwdPower;
                case 4:
                    return x.RevPower;
                case 5:
                    return x.ImmunityLevel;
                case 6:
                    return x.LimitImmunityLevel;
                case 7:
                    return x.swr;
                case 8:
                    return x.Loss;
                case 10:
                    return x.info;
                }
            }
        }
        break;
    }
    return {};
}

/**
 * @brief ParameterTableModel::setData
 * @details 设置指定索引的值。
 * @param idx 模型索引。
 * @param val 新的值。
 * @param role 数据角色。
 * @return 设置成功返回 true。
 */
bool ParameterTableModel::setData(const QModelIndex &idx, const QVariant &val, int role)
{
    if (!idx.isValid())
        return false;
    const int r = idx.row(), c = idx.column();

    auto asDouble = [&](const QVariant &v) { bool ok=false; double d=v.toDouble(&ok); return ok?d:0.0; };

    switch (m_kind) {
    case ParamTableKind::Attenuation:
        if (r < m_att.attList.size() && role == Qt::EditRole) {
            if (c == 0)
                m_att.attList[r].Freq = asDouble(val) * 1e6;
            else
                m_att.attList[r].Att = asDouble(val);
            emit dataChanged(idx, idx);
            return true;
        }
        break;
    case ParamTableKind::Transducer:
        if (r < m_trans.factorsList.size() && role == Qt::EditRole) {
            switch (c) {
            case 0:                                  // Source Unit (第一列)
                m_trans.sourceUnit = val.toString(); // 从 QVariant 获取 QString
                emit dataChanged(idx, idx);          // 通知视图该单元格已更改
                return true;
            case 1:                                                // Frequency (第二列)
                m_trans.factorsList[r].Freq = asDouble(val) * 1e6; // MHz -> Hz
                emit dataChanged(idx, idx);
                return true;
            case 2: // Factors (第三列)
                m_trans.factorsList[r].Factors = asDouble(val);
                emit dataChanged(idx, idx);
                return true;
            case 3:                                  // Target Unit (第四列)
                m_trans.targetUnit = val.toString(); // 从 QVariant 获取 QString
                emit dataChanged(idx, idx);          // 通知视图该单元格已更改
                return true;
            }
        }
        break;
    case ParamTableKind::LimitLine:
        if (r < m_limit.limitList.size() && role == Qt::EditRole) {
            if (c == 0)
                m_limit.limitList[r].Freq = asDouble(val) * 1e6;
            else
                m_limit.limitList[r].Limit = asDouble(val);
            emit dataChanged(idx, idx);
            return true;
        }
        break;
    case ParamTableKind::Frequency:
        if (r < m_freq.size() && role == Qt::EditRole) {
            if (c == 0)
                m_freq[r].Freq = asDouble(val) * 1e6;
            emit dataChanged(idx, idx);
            return true;
        }
        break;
    case ParamTableKind::Cal:
        if (r < m_cal.size()) {
            auto &x = m_cal[r];
            if (role == Qt::CheckStateRole && c == 9) {
                x.CloseLoop = (val.toInt() == Qt::Checked);
                emit dataChanged(idx, idx, {Qt::CheckStateRole});
                return true;
            }
            if (role == Qt::EditRole) {
                switch (c) {
                case 0:
                    break;
                case 1:
                    x.Freq = asDouble(val) * 1e6;
                    break;
                case 2:
                    x.Amplitude = asDouble(val);
                    break;
                case 3:
                    x.FwdPower = asDouble(val);
                    break;
                case 4:
                    x.RevPower = asDouble(val);
                    break;
                case 5:
                    x.ImmunityLevel = asDouble(val);
                    break;
                case 6:
                    x.LimitImmunityLevel = asDouble(val);
                    break;
                case 7:
                    x.swr = asDouble(val);
                    break;
                case 8:
                    x.Loss = asDouble(val);
                    break;
                case 10:
                    x.info = val.toString();
                    break;
                default:
                    break;
                }
                emit dataChanged(idx, idx);
                return true;
            }
        }
        break;
    }
    return false;
}

/**
 * @brief ParameterTableModel::flags
 * @details 返回单元格的交互标志。
 * @param idx 模型索引。
 * @return 标志集合。
 */
Qt::ItemFlags ParameterTableModel::flags(const QModelIndex &idx) const
{
    if (!idx.isValid())
        return Qt::NoItemFlags;
    Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    if (m_kind == ParamTableKind::Transducer) {
        const int column = idx.column();
        const int totalColumns = this->columnCount(); // 获取当前模型的总列数
        if (column == 0 || column == (totalColumns - 1)) {
        } else {
            // 对于 Transducer 表的其他列，允许编辑
            f |= Qt::ItemIsEditable;
        }
    } else if (m_kind == ParamTableKind::Cal && idx.column() == 10) {
        f |= Qt::ItemIsUserCheckable;
    } else {
        f |= Qt::ItemIsEditable;
    }

    return f;
}

/**
 * @brief ParameterTableModel::insertRows
 * @details 在指定位置插入若干空行。
 * @param row 插入起始行。
 * @param count 插入数量。
 * @param parent 父索引。
 * @return 插入成功返回 true。
 */
bool ParameterTableModel::insertRows(int row, int count, const QModelIndex &)
{
    if (count <= 0)
        return false;
    beginInsertRows(QModelIndex(), row, row + count - 1);
    switch (m_kind) {
    case ParamTableKind::Attenuation:
        while (count--)
            m_att.attList.insert(row, AttTableConfig {});
        break;
    case ParamTableKind::Transducer:
        while (count--)
            m_trans.factorsList.insert(row, FactorsConfig {});
        break;
    case ParamTableKind::LimitLine:
        while (count--)
            m_limit.limitList.insert(row, LimitLineConfig {});
        break;
    case ParamTableKind::Frequency:
        while (count--)
            m_freq.insert(row, FreqTableConfig {});
        break;
    case ParamTableKind::Cal:
        while (count--)
            m_cal.insert(row, CalTableConfig {});
        break;
    }
    endInsertRows();
    return true;
}
/**
 * @brief ParameterTableModel::removeRows
 * @details 删除指定范围的行。
 * @param row 起始行。
 * @param count 删除数量。
 * @param parent 父索引。
 * @return 删除成功返回 true。
 */
bool ParameterTableModel::removeRows(int row, int count, const QModelIndex &)
{
    if (count <= 0)
        return false;
    beginRemoveRows(QModelIndex(), row, row + count - 1);
    switch (m_kind) {
    case ParamTableKind::Attenuation:
        while (count--)
            m_att.attList.removeAt(row);
        break;
    case ParamTableKind::Transducer:
        while (count--)
            m_trans.factorsList.removeAt(row);
        break;
    case ParamTableKind::LimitLine:
        while (count--)
            m_limit.limitList.removeAt(row);
        break;
    case ParamTableKind::Frequency:
        while (count--)
            m_freq.removeAt(row);
        break;
    case ParamTableKind::Cal:
        while (count--)
            m_cal.removeAt(row);
        break;
    }
    endRemoveRows();
    return true;
}
